from qcloud_cos import CosConfig, CosServiceError
from qcloud_cos import CosS3Client

from projectmanager import settings


class CosTencent:
    def __init__(self):
        self.config = CosConfig(Region=settings.TENCENT_COS_REGION,
                                SecretId=settings.TENCENT_COS_SECRET_ID,
                                SecretKey=settings.TENCENT_COS_SECRET_KEY,
                                )
        self.client = CosS3Client(self.config)

    def create_bucket(self, bucket_name):
        """

        :param bucket_name: 桶名称-appid for example：examplebucket-1250000000
        :return:
        """
        result = {'status': True}
        try:
            self.client.create_bucket(
                Bucket=bucket_name,
                ACL="public-read"  # private  /  public-read / public-read-write
            )
            # 配置跨域信息
            cors_config = {
                'CORSRule': [
                    {
                        'AllowedOrigin': '*',
                        'AllowedMethod': ['GET', 'PUT', 'HEAD', 'POST', 'DELETE'],
                        'AllowedHeader': "*",
                        'ExposeHeader': "*",
                        'MaxAgeSeconds': 500
                    }
                ]
            }
            self.client.put_bucket_cors(
                Bucket=bucket_name,
                CORSConfiguration=cors_config
            )
            result['status'] = True
        except CosServiceError:
            result['status'] = False
        finally:
            return result

    def delete_empty_bucket(self, bucket_name):
        result = {'status': True}
        try:
            response = self.client.delete_bucket(
                Bucket=bucket_name
            )
            result['status'] = True
        except CosServiceError:
            result['status'] = False
        finally:
            return result

    def browse_bucket(self):
        """
        bucket_list格式：
                {'Owner':
                    {'ID': 'qcs::cam::uin/100011758814:uin/100011758814',
                    'DisplayName': '100011758814'},
                'Buckets':
                    {'Bucket':
                        [
                        {'Name': 'test1-1300450009',
                          'Location': 'ap-beijing',
                          'CreationDate': '2022-05-12T05:33:13Z',
                          'BucketType': 'cos'},
                        ]
                    }
                }
        """
        bucket_list = self.client.list_buckets()
        return bucket_list

    def upload(self, bucket_name, key, image_object):
        self.client.upload_file_from_buffer(
            Bucket=bucket_name,
            Key=key,
            Body=image_object
        )
        return f"https://{bucket_name}.cos.{settings.TENCENT_COS_REGION}.myqcloud.com/{key}"

    def download(self):
        pass

    def delete_file(self, bucket_name, key):
        self.client.delete_object(
            Bucket=bucket_name,
            Key=key)

    def delete_file_list(self, bucket_name, key_list):
        objects = {
            "Quiet": "true",
            "Object": key_list
        }
        """
        [{"Key": "file_name1"},
         {"Key": "file_name2"}]
        """
        self.client.delete_objects(
            Bucket=bucket_name,
            Delete=objects
        )

    def check_object(self, bucket_name, key):
        """
        返回COS对象的详细信息
        :param bucket_name:
        :param key:
        :return:
        {'Content-Type': 'image/jpeg',
        'Content-Length': '4991',
        'Connection': 'keep-alive',
        'Accept-Ranges': 'bytes',
        'Date': 'Wed, 18 May 2022 10:15:31 GMT',
        'ETag': '"361b3b91ece91d268956a4e67cfe92d4"',
        'Last-Modified': 'Wed, 18 May 2022 06:51:14 GMT',
        'Server': 'tencent-cos',
        'x-cos-hash-crc64ecma': '1400565792409190827',
        'x-cos-request-id': 'NjI4NGM3NDNfYWI0ZTQ0MGJfMTA3Y2VfNjM1ZDdhNA=='}
        """
        return self.client.head_object(Bucket=bucket_name, Key=key)

    def browse_file(self, bucket_name):
        """
        遍历当前桶内的所有文件
        :param bucket_name:
        :return:
        {'Name': '13020868780-1652838235-1300450009',
        'EncodingType': 'url',
        'Prefix': None,
        'Marker': None,
        'MaxKeys': '1000',
        'IsTruncated': 'false',
        'Contents':
        [{'Key': '1652931676217_left-bottom2.jpg',
        'LastModified': '2022-05-19T03:41:16.000Z',
        'ETag': '"d827b6fd75979956ffa1848e6b08e96a"',
        'Size': '28596',
        'Owner': {'ID': '1300450009', 'DisplayName': '1300450009'},
        'StorageClass': 'STANDARD'}, ......]
        """
        return self.client.list_objects(Bucket=bucket_name)

    def delete_full_bucket(self, bucket_name):
        try:
            # 找到文件 & 删除
            while True:
                part_objects = self.client.list_objects(bucket_name)

                # 已经删除完毕，获取不到值
                contents = part_objects.get('Contents')
                if not contents:
                    break

                # 批量删除
                objects = {
                    "Quiet": "true",
                    "Object": [{'Key': item["Key"]} for item in contents]
                }
                self.client.delete_objects(bucket_name, objects)

                if part_objects['IsTruncated'] == "false":
                    break

            # 找到碎片 & 删除
            while True:
                part_uploads = self.client.list_multipart_uploads(bucket_name)
                uploads = part_uploads.get('Upload')
                if not uploads:
                    break
                for item in uploads:
                    self.client.abort_multipart_upload(bucket_name, item['Key'], item['UploadId'])
                if part_uploads['IsTruncated'] == "false":
                    break

            self.client.delete_bucket(bucket_name)
        except CosServiceError as e:
            pass

